package com.shiguiwu.springmybatis.spring.aop.principle;

import org.springframework.aop.MethodBeforeAdvice;
import org.springframework.aop.framework.AdvisedSupport;
import org.springframework.aop.framework.AopProxy;
import org.springframework.aop.framework.AopProxyFactory;
import org.springframework.aop.framework.DefaultAopProxyFactory;
import org.springframework.aop.framework.ProxyFactory;

import java.lang.reflect.Method;

/**
 * @description: 前置方法通知
 * @author: stone
 * @date: Created by 2021/5/20 20:18
 * @version: 1.0.0
 * @pakeage: com.shiguiwu.springmybatis.spring.aop.principle
 */
public class BeforeMethodTestsV2 {

    public static void main(String[] args) {
//        ProxyFactory proxyFactory = new ProxyFactory(new FunsService());
        AdvisedSupport advisedSupport = new AdvisedSupport();
        advisedSupport.addAdvice(new MethodBeforeAdvice() {
            @Override
            public void before(Method method, Object[] objects, Object o) throws Throwable {
                String username = (String) objects[0];
                if (!"路人".equals(username)) {
                    throw new RuntimeException(String.format("%s非法访问", username));
                }
            }
        });

        advisedSupport.addAdvice(new MethodBeforeAdvice() {
            @Override
            public void before(Method method, Object[] objects, Object o) throws Throwable {
                System.out.println("第二个增强");
            }
        });

        advisedSupport.addAdvice(new MethodBeforeAdvice() {
            @Override
            public void before(Method method, Object[] objects, Object o) throws Throwable {
                System.out.println("第三个增强!!");
            }
        });

        advisedSupport.setTarget(new FunsService());
        //2.根据配置信息获取AopProxy对象，AopProxy用来负责创建最终的代理对象
        // AopProxy接口有2个实现类（JDK动态代理、cglib代理）
        // 具体最终会使用哪种方式，需要根据AdvisedSupport中指定的参数来判断
        // 创建AopProxy使用了简单工厂模式
        advisedSupport.setProxyTargetClass(true);
        AopProxyFactory aopProxyFactory = new DefaultAopProxyFactory();

        //通过AopProxy工厂获取AopProxy对象
        AopProxy aopProxy = aopProxyFactory.createAopProxy(advisedSupport);

        Object proxy = aopProxy.getProxy();
//        FunsService funsService = (FunsService) proxy;
//        funsService.getBalance("路人");
////        funsService.getBalance("张学友");
//        funsService.recharge("路人", 100);
//        System.out.println(funsService.getBalance("路人"));


        //todo 实验，创建代理的代理
        ProxyFactory proxyFactory = new ProxyFactory();

        //添加目标对象
        proxyFactory.setTarget(proxy);

        //添加增强
        proxyFactory.addAdvice(new MethodBeforeAdvice() {
            @Override
            public void before(Method method, Object[] objects, Object o) throws Throwable {
                System.out.println("我在你方法之前执行");
            }
        });

        Object proxy1 = proxyFactory.getProxy();

        FunsService funsService1 = (FunsService) proxy1;
        //funsService1.getBalance("路人");
//        funsService.getBalance("张学友");
        funsService1.recharge("路人", 100);
        //System.out.println(funsService1.getBalance("路人"));

    }
}
